#ifndef MATH_H
#define MATH_H

#include <math.h>

#include "Framework/Prerequisites.h"
#include "Math/Radian.h"

namespace tyro
{

	namespace Math
	{


		static const FLOAT_32 INFINITY =	1.0E+12f;
		static const FLOAT_32 PI	   =	3.1415926536f;
		static const FLOAT_32 TWO_PI   =	6.2831853071f;
		static const FLOAT_32 DEGTORAD =	0.0174532925f;
		static const FLOAT_32 RADTODEG =	57.295779513f;


		Matrix4f CreateViewMatrix(const Vector3f& position, const Quaternionf& orientation, const Matrix4f* reflectMatrix = 0 );

		inline FLOAT_32	RadiansToDegrees( FLOAT_32 radians ) { return radians * RADTODEG; }

		template < class T >
		inline Radian<T> DegreesToRadian( T degrees ) { return Radian<T>(degrees * DEGTORAD); } 

		template < class T >
		inline T RandomNumber( const T minNum, const T maxNum )
		{
			return  minNum + (T)rand() / ((T)RAND_MAX / ( maxNum - minNum));
		}

		template < class T >
		inline T RandomSeededNumber( const T minNum, const T maxNum )
		{
			srand((UINT_32)time(0));
			return  minNum + (T)rand() / ((T)RAND_MAX / ( maxNum - minNum));
		}

		inline bool TestPowerOf2(UINT_32 val)
		{
			return (val & (val - 1)) == 0;
		}

		inline UINT_32 NextPowerOf2( UINT_32 x, UINT_32 lowerBound = 1 )
		{
			assert( Math::TestPowerOf2(lowerBound) );
			UINT_32 roundedX = lowerBound;
			while( roundedX < x )
			{
				roundedX <<= 1;
			}
			return roundedX;
		}

		template < class T >
		static inline T Abs( T value )
		{
			return T(fabs(value));
		}

		template < class T >
		static inline T Sqr( T value )
		{
			return value * value;
		}

		template < class T >
		static inline T Sqrt( T value )
		{
			return T(sqrt(value));
		}

		template < class T >
		static inline T Tan( const Math::Radian<T>& value )
		{
			return T(tan(value.ToRadians()));
		}
		



	}
}

#endif